/*
 * Copyright (c) 2012 swing-on-fire Team
 * 
 * This file is part of Swing-On-Fire (http://code.google.com/p/swing-on-fire), licensed under the terms of the MIT
 * License (MIT).
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
 * Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package com.google.code.swingonfire.image;

import java.awt.Image;
import java.io.IOException;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;

public class ImageCache
{

    private static final Set<String> LOCATIONS = new LinkedHashSet<String>();
    private static final Set<String> EXTENSIONS = new LinkedHashSet<String>();
    private static final Map<String, Image> IMAGES = new LinkedHashMap<String, Image>();
    private static final Map<String, Icon> ICONS = new LinkedHashMap<String, Icon>();

    static
    {
        addLocation("");

        addExtension("");
        addExtension(".png");
        addExtension(".jpg");
        addExtension(".gif");
    }

    public static void addLocation(String location)
    {
        if ((location.length() > 0) && (!location.endsWith("/")))
        {
            location += "/";
        }

        LOCATIONS.add(location);
    }

    public static void addExtension(String extension)
    {
        if ((extension.length() > 0) && (!extension.startsWith(".")))
        {
            extension = "." + extension;
        }

        EXTENSIONS.add(extension);
    }

    public static Image getImage(String name)
    {
        Image image = IMAGES.get(name);

        if (image == null)
        {
            image = resolveImage(name);

            if (image == null)
            {
                throw new IllegalArgumentException(String.format("Image %s not found", name));
            }

            IMAGES.put(name, image);
        }

        return image;
    }

    public static Icon getIcon(String name)
    {
        Icon icon = ICONS.get(name);

        if (icon == null)
        {
            icon = resolveIcon(name);

            if (icon == null)
            {
                throw new IllegalArgumentException(String.format("Icon %s not found", name));
            }

            ICONS.put(name, icon);
        }

        return icon;
    }

    private static Image resolveImage(String name)
    {
        URL url = resolveURL(name);

        if (url == null)
        {
            return null;
        }

        try
        {
            return ImageIO.read(url);
        }
        catch (IOException e)
        {
            throw new IllegalArgumentException("Failed to read image " + url, e);
        }
    }

    private static Icon resolveIcon(String name)
    {
        URL url = resolveURL(name);

        if (url == null)
        {
            return null;
        }

        return new ImageIcon(url);
    }

    private static URL resolveURL(String name)
    {
        for (String location : LOCATIONS)
        {
            for (String extension : EXTENSIONS)
            {
                String resource = location + name + extension;
                URL url = ImageCache.class.getClassLoader().getResource(resource);

                if (url != null)
                {
                    return url;
                }
            }
        }

        return null;
    }
}
